package com.jarveis.dbs.core;

import java.util.List;

import org.apache.log4j.Logger;

import com.jarveis.dbs.Constants;
import com.jarveis.dbs.core.bean.CallBean;
import com.jarveis.dbs.core.bean.FunctionBean;
import com.jarveis.dbs.core.filter.DeviceFilter;
import com.jarveis.frame.util.Param;
import com.sun.xml.internal.bind.v2.runtime.reflect.opt.Const;

/**
 * @desc 服务代理
 * @author liuguojun
 * @date 2014-06-12
 */
public class ServiceProxy {

	private static final Logger logger = Logger.getLogger(ServiceProxy.class);

	/**
	 * 代理执行
	 * 
	 * @param service
	 * @param vo
	 * @return Param
	 * @throws Exception
	 */
	public static Param callService(Service service, Param vo) throws Exception {

		String device = vo.getHead().getString(Constants.LABEL_DEVICE);
		String token = vo.getHead().getString(Constants.LABEL_TOKEN);
		String funcId = vo.getHead().getString(Param.LABEL_FUNCID);
		String dataType = vo.getHead().getString(Param.LABEL_DATATYPE);
		
		Param out = service.callService(vo);

		if (out == null) {
			out = new Param(Param.RESP);
			out.getHead().setProperty(Param.LABEL_ERROR, Param.ERROR_EXCEPTION);
		}
		
		int errcode = out.getHead().getInteger(Param.LABEL_ERROR);
		if (errcode < 1 && errcode >= 2000){
			out.getHead().setProperty(Param.LABEL_ERROR, Constants.ERROR_RETURN);
		}

		out.getHead().setProperty(Constants.LABEL_DEVICE, device);
		out.getHead().setProperty(Constants.LABEL_TOKEN, token);
		out.getHead().setProperty(Param.LABEL_FUNCID, funcId);
		out.getHead().setProperty(Param.LABEL_DATATYPE, dataType);

		return out;
	}

	/**
	 * 代理执行
	 * 
	 * @param funcId
	 * @param vo
	 * @return Param
	 * @throws Exception
	 */
	public static Param callService(String funcId, Param vo) throws Exception {

		Service service = ServiceFactory.getService(funcId);
		Param out = callService(service, vo);

		String errCode = out.getHead().getString(Param.LABEL_ERROR);
		if (!Param.ERROR_SUCCESS.equals(errCode)) {
			return out;
		}

		// 处理子程序
		FunctionBean function = DBContext.getInstance().getFunction(funcId);
		List<CallBean> calls = function.getCalls();
		if (calls == null || calls.isEmpty()) {
			return out;
		}

		for (CallBean callBean : calls) {
			String callCode = callBean.getCode();
			// 同步处理
			logger.info(out.toString());
			Param callOut = callService(callCode, out);
			logger.info(callOut.toString());

			errCode = callOut.getHead().getString(Param.LABEL_ERROR);
			if (!Param.ERROR_SUCCESS.equals(errCode)) {
				// 如果子程序错误，将整个程序标识错误，方便回滚
				out.getHead().setProperty(Param.LABEL_ERROR, errCode);
				break;
			}

			Param child = callOut.getBody().getChild(null);
			if (child == null) {
				continue;
			}
			// 将子程序的执行结果，添加到回执中，方便后续程序进行处理
			out.getBody().addParam(child.getElement(false));
		}

		return out;
	}

}